﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.IO;

using AvalonDock;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd;

namespace delge_squirreleditor
{
    /// <summary>
    /// Interaction logic for ScriptEditor.xaml
    /// </summary>
    public partial class ScriptEditor : DocumentContent
    {
        private string _filename;

        /// <summary>
        /// The file name of the script that the editor is editing on disk.
        /// </summary>
        public string Filename 
        {
            get { return _filename; }
            protected set
            {
                _filename = value;
                Shortname = Project.ShortName(value);
            }
        }
        /// <summary>
        /// The filepath of the file on disk.
        /// </summary>
        public string Filepath { get; protected set; }
        /// <summary>
        /// A shortend name, used to display the filename.
        /// </summary>
        public string Shortname { get; protected set; }
        /// <summary>
        /// Has the file been edited?
        /// </summary>
        public bool OutOfDate { get; protected set; }

        

        public static List<ScriptEditor> ScriptEditorList
        {
            get { return _scriptEditorList; }
        }

        protected static List<ScriptEditor> _scriptEditorList = new List<ScriptEditor>();

        public ScriptEditor(string scriptPath)
        {
            InitializeComponent();

            TextReader reader = new StreamReader(scriptPath);
            Filename = Path.GetFileName(scriptPath);
            Filepath = scriptPath;

            Title = Shortname;
            ToolTip = Filepath;

            textEditor.Name = "textEditor";
            textEditor.FontFamily = new FontFamily("Consolas");
            textEditor.FontSize = 12;
            textEditor.ShowLineNumbers = true;
            textEditor.Text = reader.ReadToEnd(); reader.Close();
            textEditor.SyntaxHighlighting = HighlightingLoader.Load(new XmlTextReader("SQUIRREL-Mode.xhsd"), HighlightingManager.Instance);

            textEditor.TextChanged += new EventHandler(TextEditor_TextChanged);

            contextMenuItem_Copy.Click += new RoutedEventHandler(contextMenuItem_Copy_Click);
            contextMenuItem_Cut.Click += new RoutedEventHandler(contextMenuItem_Cut_Click);
            contextMenuItem_Paste.Click += new RoutedEventHandler(contextMenuItem_Paste_Click);
            contextMenuItem_SelectAll.Click += new RoutedEventHandler(contextMenuItem_SelectAll_Click);

            DataContext = this;
        }

        public void Save()
        {
            SaveAs(this.Filepath);
        }

        public void SaveAs(string filepath)
        {
            this.Filepath = filepath;
            this.Filename = Path.GetFileName(filepath);

            // If these both match, no directory was given so we
            // get it from the path.getfullpath method.
            if (this.Filepath == this.Filename)
                this.Filepath = Path.GetFullPath(this.Filename);

            Title = this.Shortname;
            ToolTip = this.Filepath;

            TextWriter writer = new StreamWriter(filepath);
            writer.Flush();
            writer.Write(textEditor.Text);
            writer.Close();

            OutOfDate = false;
        }

        public static bool CloseAll()
        {
            bool closed = true;
            List<ScriptEditor> tmpList = new List<ScriptEditor>(ScriptEditorList);

            foreach (ScriptEditor editor in tmpList)
            {
                closed = editor.Close();
                if (!closed) // Close should cancel
                    return false;
            }

            return true;
        }

        public static void SaveAll()
        {
            foreach (ScriptEditor editor in ScriptEditorList)
                editor.Save();
        }

        public void Rename(string newFilePath)
        {
            File.Move(Filepath, newFilePath);
            Filename = Path.GetFileName(newFilePath);
            Filepath = newFilePath;
            Title = Shortname += "*";
            ToolTip = Filepath;
            OutOfDate = true;
        }

        public override void Show(DockingManager manager)
        {
            if (!ScriptEditorList.Contains(this))
                ScriptEditorList.Add(this);
            base.Show(manager);
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            if (OutOfDate)
            {
                MessageBoxResult result = MessageBox.Show("Save changes to \"" + Filename + "\"?", "DelGE Squirrel Editor", MessageBoxButton.YesNoCancel, MessageBoxImage.Question, MessageBoxResult.Yes);
                switch (result)
                {
                    case MessageBoxResult.Yes:
                        Save();
                        e.Cancel = false;
                        break;

                    case MessageBoxResult.No:
                        e.Cancel = false;
                        break;

                    case MessageBoxResult.Cancel:
                        e.Cancel = true;
                        break;
                }
            }

            if (e.Cancel == false)
                ScriptEditorList.Remove(this);

            base.OnClosing(e);
        }

        void TextEditor_TextChanged(object sender, EventArgs e)
        {
            if (!OutOfDate)
            {
                Title += "*";
                OutOfDate = true;
            }
        }

        void contextMenuItem_Copy_Click(object sender, RoutedEventArgs e)
        {
            textEditor.Copy();
        }

        void contextMenuItem_Cut_Click(object sender, RoutedEventArgs e)
        {
            textEditor.Cut();
        }

        void contextMenuItem_Paste_Click(object sender, RoutedEventArgs e)
        {
            textEditor.Paste();
        }

        void contextMenuItem_SelectAll_Click(object sender, RoutedEventArgs e)
        {
            textEditor.SelectAll();
        }
    }
}
